#include "myobject.h"
#include "Path.h"
#include "CMemoryFile.h"
using namespace io;

namespace fireplane
{
	Path::Path(){}
	Path::~Path(){}

	const char* _all_path_file[] = {
		"path/level0/bezier.bin"
	};

	void Path::loadPath( int level ){
		unsigned long size;
		unsigned char* buffer = CCFileUtils::sharedFileUtils()->getFileData(_all_path_file[level],"rb",&size);

		CMemoryFile* file = createMemoryReadFile(buffer,size,_all_path_file[level],true);
		_loadPathFile(file);
	}
	void Path::_loadPathFile(CMemoryFile* file){
		int path_count = 0;
		int path_index  = 0;
		int path_name_len = 0;
		int bezier_count = 0;
		int bezier_index = 0;

		file->read((char*)&path_count,sizeof(int));
		while(path_index < path_count)
		{
			file->read((char*)&path_name_len,sizeof(int));
			char* path_name = new char[path_name_len];
			file->read(path_name,path_name_len);
			file->read((char*)&bezier_count,sizeof(int));

			BezierList *pBezierList = new BezierList;
			_all_path_map.insert(make_pair(path_name,pBezierList));

			bezier_index = 0;
			while (bezier_index < bezier_count)
			{
				Bezier* pBezier = new Bezier;
				for( int i = e_bezier_point_start ; i < e_bezier_point_max ; i++){
					int x = 0,y = 0;

					file->read((char*)&x,sizeof(int));
					file->read((char*)&y,sizeof(int));
					pBezier->point[i] = CCPointMake(x*2,y*2);
				}
	
				pBezierList->push_back(pBezier);
				bezier_index++;
			}
			path_index++;
		}	
	}

	BezierList* Path::getBezierList(string name)
	{
		PathMap::iterator it = _all_path_map.find(name);
		if(it != _all_path_map.end()){
			return (BezierList*)it->second;
		}
		return NULL;
	}

	BezierList* Path::_loadNPCPathFile(int level,string npc_name){
		int bezier_count = 0;
		int bezier_index = 0;
		
		char npcFilePath[256]={0};
		sprintf(npcFilePath,"path/level%d/%s",level,npc_name.c_str());

		unsigned long size;
		unsigned char* buffer = CCFileUtils::sharedFileUtils()->getFileData(npcFilePath,"rb",&size);
		if (buffer == NULL)
			return NULL;

		CMemoryFile* file = createMemoryReadFile(buffer,size,npcFilePath,true);

		file->read((char*)&bezier_count,sizeof(int));

		BezierList *pBezierList = new BezierList;
		_all_path_cache.insert(make_pair(npc_name,pBezierList));

		bezier_index = 0;
		while (bezier_index < bezier_count)
		{
			Bezier* pBezier = new Bezier;
			for( int i = e_bezier_point_start ; i < e_bezier_point_max ; i++){
				int x = 0,y = 0;

				file->read((char*)&x,sizeof(int));
				file->read((char*)&y,sizeof(int));
				pBezier->point[i] = CCPointMake(x*2,y*2);
			}

			pBezierList->push_back(pBezier);
			bezier_index++;
		}

		return pBezierList;
	}

	BezierList* Path::getNPCPath(int level,string npc_name)
	{
		PathMap::iterator it = _all_path_cache.find(npc_name);
		if(it != _all_path_cache.end()){
			return (BezierList*)it->second;
		}

		return _loadNPCPathFile(level,npc_name);
	}

	CCPoint Path::hornbez2(CCPoint *point, float t)
	{
		CCPoint p1 = point[e_bezier_point_start];
		CCPoint cp = point[e_bezier_point_ctrl];
		CCPoint p2 = point[e_bezier_point_end];

		float c1x,c1y,c2x,c2y,px,py;

		c1x = p1.x + ( cp.x - p1.x ) * t;
		c1y = p1.y + ( cp.y - p1.y ) * t;
		c2x = cp.x + ( p2.x - cp.x ) * t;
		c2y = cp.y + ( p2.y - cp.y ) * t;

		px = c1x + ( c2x - c1x ) * t;
		py = c1y + ( c2y - c1y ) * t;
			
		return CCPointMake(px,py);
	}

	Path* Path::getPath()
	{
		if(!_s_Path){
			_s_Path = new Path();
		}

		return _s_Path;
	}

	Path* Path::_s_Path = NULL;
}